/** \file
* Declarations for the XmlProperty/TypedXmlProperty classes.
* This file is part of Chorus, available at
* http://code.google.com/p/chorus-twitter/ . This file and all associated files
* and derivative works are bound by the terms of the LGPL 3.0 license,
* available at http://www.gnu.org/licenses/lgpl-3.0-standalone.html .
* \par Subversion URL:
* \$URL: http://chorus-twitter.googlecode.com/svn/branches/cpp/src/xml/XmlProperty.hpp $
* \version \$Rev: 153 $
* \date    \$Date: 2010-04-06 07:43:42 +0000 (Tue, 06 Apr 2010) $
*/

#pragma once

#include <sstream>

/// The abstract, untyped XML property class.
class XmlProperty
{
protected:
	/// The constructor. Cannot be called directly.
	XmlProperty() {}
public:
	virtual ~XmlProperty() {}

public:
	/// Set the property by parsing a string.
	/// \param text The string to parse.
	virtual void parse(const char *text) = 0;

	/// Set the property by parsing a string.
	/// \param text The string to parse.
	virtual void parse(const std::string &text) = 0;
};

/// The typed XML property class. PropType is the value that this property
/// stores.
template <typename PropType>
class TypedXmlProperty : public XmlProperty
{
public:
	/// The default constructor.
	TypedXmlProperty() :
		value() {}

	/// A constructor to initialize the value.
	/// \param valInit The value to which this property should be initialized.
	TypedXmlProperty(const PropType &valInit) :
		value(valInit) {}

public:
	/// Set the property by parsing a string.
	/// \param text The string to parse.
	virtual void parse(const char *text)
	{
		std::istringstream str(text);
		str >> value;
	}

	/// Set the property by parsing a string.
	/// \param text The string to parse.
	virtual void parse(const std::string &text)
	{
		std::istringstream str(text);
		str >> value;
	}

	/// Set the property directly.
	/// \param to The value to which the property should be set.
	void set(const PropType &to)
	{
		value = to;
	}

	/// Get the property value.
	/// \return The property value.
	const PropType &get() const
	{
		return value;
	}

private:
	/// The property value.
	PropType value;
};

/// Template specialization for std::string where no stringstream is needed.
template <>
FORCE_EXPORT
void TypedXmlProperty<std::string>::parse(const char *text);

/// Template specialization for std::string where no stringstream is needed.
template <>
FORCE_EXPORT
void TypedXmlProperty<std::string>::parse(const std::string &text);
